/*
	Copyright (C) 2010 2011 Rémi Thebault

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>

#include "ganttcycle.h"
#include "ganttlink.h"
#include "taskviewhelper.h"
#include "procycle.h"


GanttCycle::GanttCycle(ProCycle* app, PC::Cycle* cycle) :
		GanttMTask(app, cycle, this)
{
	replaceChildren();

	for (PC::Link::const_iterator li=cycle->linkBegin();
		 li!=cycle->linkEnd(); ++li) {
		GanttLink* gl = new GanttLink(app, this, *li);
		addLink(gl);
		gl->setPos(0, 0);
	}

}



void GanttCycle::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {

}



void GanttCycle::mousePressEvent(QGraphicsSceneMouseEvent *event) {
	event->ignore();
}



void GanttCycle::replaceChildren() {
	TaskViewHelper tvh (m_task);
	QList<int> childrenPos = tvh.visualChildrenPos();
	for(int i=0; i<m_gtasks.size(); i++) {
		GanttTask* gt = m_gtasks.at(i);
		gt->setPos(0, app()->rowHeight()*childrenPos.at(i));
		gt->replaceChildren();
	}
}




QRectF GanttCycle::boundingRect() const {
	TaskViewHelper tvh (m_task);
	return QRectF(
			0,
			0,
			scene()->width(),
			app()->rowHeight()*(tvh.visualChildrenHeight())
	);
}





void GanttCycle::addLink(GanttLink *gl) {
	m_glinks.append(gl);
}


void GanttCycle::removeLink(GanttLink *gl) {
	m_glinks.removeAll(gl);
}


GanttLink* GanttCycle::findGLink(PC::Link *link) {
	foreach(GanttLink* gl, m_glinks) {
		if (link == gl->link()) {
			return gl;
		}
	}
}

void GanttCycle::resetTask(PC::Task *task) {
	foreach(GanttLink* gl, m_glinks) {
		scene()->removeItem(gl);
	}
	qDeleteAll(m_glinks);
	GanttMTask::resetTask(task);
	for (PC::Link::const_iterator li=cycle()->linkBegin();
		 li!=cycle()->linkEnd(); ++li) {
		GanttLink* gl = new GanttLink(app(), this, *li);
		addLink(gl);
		gl->setPos(0, 0);
		gl->syncToExpansion();
	}
}


QList<GanttLink*> GanttCycle::inGLinksForGTask(GanttTask *gt) {
	QList<GanttLink*> list;
	foreach(GanttLink* gl, m_glinks) {
		if (gl->gtTo() == gt) {
			list.append(gl);
		}
	}
	return list;
}

QList<GanttLink*> GanttCycle::outGLinksForGTask(GanttTask *gt) {
	QList<GanttLink*> list;
	foreach(GanttLink* gl, m_glinks) {
		if (gl->gtFrom() == gt) {
			list.append(gl);
		}
	}
	return list;
}



void GanttCycle::processExpansionChange(PC::Task *task) {
	GanttMTask* gmt = dynamic_cast<GanttMTask*>(resolvAbsoluteTask(task->tbsId()));
	if (gmt) {
		gmt->processExpansionChange();
	}
	foreach (GanttLink* gl, m_glinks) {
		gl->syncToExpansion();
	}
}


void GanttCycle::processScheduled() {
	foreach(GanttLink* gl, m_glinks) {
		gl->update(gl->boundingRect());
	}
}



void GanttCycle::setCycleProp(PC::Cycle::Property p, const QVariant &value) {
	GanttMTask::setCycleProp(p, value);
	foreach(GanttLink* gl, m_glinks) {
		gl->setCycleProp(p, value);
	}
}


void GanttCycle::editModeChanged() {
	GanttMTask::editModeChanged();
	foreach(GanttLink* gl, m_glinks) {
		gl->editModeChanged();
	}
	setZValue(0);
}
